<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>

<script type="text/javascript">
	// 获取滚动条长度
	function getScrollOffset() {
	    if (window.pageYOffset) {
	        return {
	            x: window.pageXOffset,
	            y: window.pageYOffset
	        }
	    }

	    return {
	    	//IE Firefox Opera 标准模式下使用 document.documentElement.scrollLeft 获取页面的水平滚动条位置，
	    	//而混杂模式下则是使用 document.body.scrollLeft。Chrome Safari 在两种文档模式下均使用 document.body.scrollLeft 获取页面的水平滚动条位置。
	        x: document.documentElement.scrollLeft + document.body.scrollLeft,
	        y: document.documentElement.scrollTop + document.body.scrollTop
	    }
	}

	function getViewportOffset() {

	    if (window.innerWidth) {
	        return {
	            w: window.innerWidth,
	            h: window.innerHeight
	        }
	    }
	    if (document.compatMode == "CSS1Compat") {		//表明当前文档的渲染模式是"混杂模式"("BackCompat")还是"标准模式"("CSS1Compat")
	        return {
	            w: document.documentElement.clientWidth,
	            h: document.documentElement.clientHeight
	        }
	    } else if (document.compatMode == "BackCompat") {
	        return {
	            w: document.body.clientWidth,
	            h: document.body.clientHeight
	        }
	    }
	}

	function getElementOffset(ele) {
	    var box = ele.getBoundingClientRect();			//返回元素的大小及其相对于视口的位置。
	    var w = box.width || (box.right - box.left);
	    var h = box.height || (box.bottom - box.top);
	    return {
	        w: w,
	        h: h
	    }
	}

	function getElementPostion(ele) {

	    var x = 0,
	        y = 0;

	    while (ele != document.body) {
	        x += ele.offsetLeft;		//offsetLeft 获取的是相对于父对象的左边距
	        y += ele.offsetTop;
	        ele = ele.offsetParent;
	    }

	    return {
	        x: x,
	        y: y
	    }
	}

	function getStyle(obj, styleProp) {

	    if (obj.currentStyle) {
	        return obj.currentStyle[styleProp];
	    } else {
	        return window.getComputedStyle(obj, null)[styleProp];
	        //getComputedStyle()方法接受两个参数：要取得计算样式的元素和一个伪元素字符串（例如“:after”）。如果不需要伪元素信息，第二个参数可以是null。
	        //getComputerStyle()方法返回一个CSSStyleDeclaration对象，其中包含当前元素的所有计算的样式
	    }
	}

	function addEvent(elem, type, handler) {

	    if(elem.addEventListener) {
	        elem.addEventListener(type, handler, false);
	        //例 div.addEventListener('click', function(){}, false);
	    }else if(elem.attachEvent) {

	        elem['temp' + type + handler] = handler;
	        elem[type + handler] = function () {
	            elem['temp' + type + handler].call(elem);
	            //其实这句话就相当于是handler.call(elem);但因为handler是function(){...};
	            //如果这么写浏览器不识别:function(){...}.call(elem);
	        };
	        elem.attachEvent('on' + type, elem[type + handler]);
	        //其实就相当于handler.call(elem);

	    }else{
	        elem['on' + type] = handler;
	    }
	}

	function removeEvent(elem, type, handler) {
	    if(elem.removeEventListener) {
	        elem.removeEventListener(type, handler, false);
	    }else if(elem.detachEvent) {
	        elem.detachEvent('on' + type, handler);
	    }else{
	        elem['on' + type] = null;
	    }
	}

	function stopBubble(event) {
	    if(event.stopPropagation) {
	        event.stopPropagation();
	    }else{
	        event.cancelBubble = true;
	    }
	}

	function cancelHandler(event) {		//阻止元素发生默认的行为
	    if(event.preventDefault) {
	        event.preventDefault();
	    }else{
	        event.returnValue = false;
	    }

	}

	function drag(elem) {
	    var disX,
	        disY;
	    addEvent(elem, 'mousedown', function (e) {
	        var event = e || window.event;
	        disX = event.clientX - parseInt(getStyle(elem, 'left'));
	        disY = event.clientY - parseInt(getStyle(elem, 'top'));

	        addEvent(document, 'mousemove', mouseMove);
	        addEvent(document, 'mouseup', mouseUp);

	        stopBubble(event);
	        cancelHandler(event);
	    });
	    function mouseMove(e) {
	        var event = e || window.event;
	        elem.style.left = event.clientX - disX + "px";
	        elem.style.top = event.clientY - disY + "px";
	    }
	    function mouseUp(e) {
	        var event = e || window.event;
	        removeEvent(document, 'mousemove', mouseMove);
	        removeEvent(document, 'mouseup', mouseUp);
	    }
	}

	function asyncLoaded(url, callback) {	//异步执行
	    var script = document.createElement('script');
	    script.type = "text/javascript";
	    if(script.readyState) {			//IE; readyState 属性返回当前文档的状态,该属性返回以下值:
	    								//uninitialized - 还未开始载入;loading - 载入中;interactive - 已加载，文档与用户可以开始交互;complete - 载入完成
	        script.onreadystatechange = function () {
	            if(script.readyState == "complete" || script.readyState == "loaded") {
	                callback();
	                script.onreadystatechange = null;
	            }
	        }
	    }else{							//chrome safari firefox
	        script.onload = function () {
	            callback();
	        }
	    }
	    script.src = url;
	    document.head.appendChild(script);
	    //此函数的书写顺序一定是要先书写逻辑顺序,后加载脚本
	}

	function type(target) {
	    var typeStr = typeof(target),
	        toStr = Object.prototype.toString,
	        objStr = {
	            "[object Object]" : "object - Object",
	            "[object Array]" : "array - Object",
	            "[object Number]" : "number - Object",
	            "[object Boolean]" : "boolean - Object",
	            "[object String]" : "string - Object"
	        }
	    if(target === null) {
	        return null;
	    }else if(typeStr === "function") {
	        return "function";
	    }
	    if(typeStr !== "object") {
	        return typeStr;
	    }else{
	        return objStr[toStr.call(target)];
	        //针对包装类, 比如var a = new Number(3); Object.prototype.toString.call(a): [object Number]
	    }
	}
</script>
</body>
</html>